package org.yzhzc.common.core.utils;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SecureDigestAlgorithm;

import javax.crypto.SecretKey;

import java.util.Date;
import java.util.Map;

/**
 * @author 吖尔
 * @date 2024/10/29 5:53
 * @description
 */
public class JwtUtils {

    /**
     * 加密算法类型
     */
    private final static SecureDigestAlgorithm<SecretKey, SecretKey> ALGORITHM = Jwts.SIG.HS256;

//    /**
//     * 秘钥实例
//     * 私钥 / 生成签名的时候使用的秘钥secret，一般可以从本地配置文件中读取，切记这个秘钥不能外露，只在服务端使用，在任何场景都不应该流露出去。
//     * 一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
//     * 应该大于等于 256位(长度32及以上的字符串)，并且是随机的字符串
//     */
//    private final static String SECRET = "secretKey";
//    public static final SecretKey KEY = Keys.hmacShaKeyFor(SECRET.getBytes());

//    /**
//     * 随机生成KEY
//     */
//    private final static SecretKey KEY = Jwts.SIG.HS256.key().build();

    /**
     * 生成令牌
     *
     * @param claims 数据
     * @param secret 密钥
     * @return 令牌
     */
    public static String createToken(Map<String, Object> claims, String secret) {
//        // 创建过期时间
//        Date exprireDate = Date.from(Instant.now().plusSeconds(720));

        SecretKey secretKey = Keys.hmacShaKeyFor(secret.getBytes());

        JwtBuilder builder = Jwts.builder()
//                .id(UUID.randomUUID().toString())   // 令牌ID
//                .subject(SUBJECT)   // 主题
                .issuedAt(new Date())   // 签发时间
//                .expiration(exprireDate)    // 过期日期
//                .issuer("吖尔")    // 签发者
                .signWith(secretKey, ALGORITHM)   // 设置 key
//                //无需手动设置header中的alg,enc或zip，JJWT会自动设置
//                .header()   // 设置头部信息header
//                .add("张三", "JWT")
//                .add("alg", "HS256")
//                .add(mapValues) // 支持map
//                .and()    // 构建头部
                .claims(claims); // 设置自定义负载信息payload，支持(map)和(k,v)

        return builder.compact();
    }

    /**
     * 解析token
     *
     * @param token token
     * @return Jws<Claims>
     */
    public static Jws<Claims> parseToken(String token, String secret) {
        // 生成 secretKey
        SecretKey KEY = Keys.hmacShaKeyFor(secret.getBytes());
        return Jwts.parser()
                .verifyWith(KEY)
                .build()
                .parseSignedClaims(token);
    }

    public static JwsHeader parseHeader(String token, String secret) {
        return parseToken(token, secret).getHeader();
    }

    public static Claims parsePayload(String token, String secret) {
        return parseToken(token, secret).getPayload();
    }
}
